package vendingmachine

import vendingmachine.*
import grails.converters.JSON
import com.tb.fb.Facebook

import net.iasolution.vendingmachine.constance.*
class SynccsJob {

	def posterService
	
	private static String dewsToken = null
	
	public static void setToken(def token){
		dewsToken = token
	}

	static triggers = { 
		simple repeatInterval: 5001 , startDelay: 1000// execute job once in 5 seconds
	}

	long getCurrentTimeFromDomain(){
		long t = 0
		PaymentTransaction.list().each {
			if(it.tradeTime > t )
				t = it.tradeTime
		}
		return t
	}

	private static long beforeTime = 0
	def execute() {
		if(beforeTime==0){
			beforeTime = getCurrentTimeFromDomain()
		}
		def t1 = System.currentTimeMillis()
		try{
			def responseData  = parseResponse(queryUrl(beforeTime,t1,dewsToken))
			println "responseData : ${responseData}"
		}catch(Exception e){
			e.printStackTrace()
			return
		}
		def tmp
		responseData.each { v->
			// 1. check the item is duplicate
			// 2. check is not set on match table
			def ps = getMatchPayments(getTheSameTransaction(v.cardId,v.tradedItem))
			tmp = new PaymentTransaction( cardId : v.cardId , tradeTime:v.tradedTime , itemName:v.tradedItem , vender:"" /*FIXME*/ /*, user:u*/ )
			tmp.save()
			if(tmp.hasErrors()) tmp.errors.each { println "[x]:${it}"}

			if(ps!=null){
				// 3. save into match table
				def m = new PaymentMatch(cardId:tmp.cardId,
						coupon:getCoupon(tmp),
						transactionA:tmp,
						transactionB:ps,
						state:MatchState.findByName("un-use")
						)
				m.save()
				if(m.hasErrors()) m.errors.each { println "save Match error : ${it}" }
				// 4. send a facebook message and mail
				else {
//					postResult(m.cardId , m)
					posterService.postResult(m.cardId)
				}
			}
		}
		beforeTime = t1
	}
	
	private String queryUrl(def t1 , def t2) throws Exception {
		return queryUrl(t1,t2, null)
	}

	private String queryUrl(def t1 , def t2 , def token) throws Exception{
		println "token : ${token}"
		def queryString = "access_token=${token}&" + 
		                  "${VendingConstance.PARAMS_START_TIME}=${t1}&" + 
						  "${VendingConstance.PARAMS_END_TIME}=${t2}"
		println 'queryString = ' + VendingConstance.getCoreServiceUrl()+ "?" +queryString
		def url = new URL(VendingConstance.getCoreServiceUrl()+ "?" + queryString)
		def connection = url.openConnection()
		connection.setRequestMethod("GET")
		connection.setRequestProperty("Accept","application/json")
		connection.doOutput = true
		println "call connect"
		connection.connect()
		println "after connect"
		println "content: ${connection?.content}"
		return connection.content.text
	}
	
//	def parseResponse(def context){
//		def r = []
////		println "######################parseResponse.context:${context} "
//		def json = JSON.parse(context)
//		json.each { device,records ->
//			records.each { v->
//				r.add([cardId:v.cardId,tradedTime:v.tradedTime,tradedItem:v.tradedItem])
//			}
//		}
//		return r
//	}
	
	def parseResponse(def context){
		println "context : ${context}"
		def r = []
		def json = JSON.parse(context)
		def tmp
			json.datalist.datalist.each { v->
				try{
					// decode base 64
					println "v : ${v}"
					tmp = JSON.parse(new String(v.rawdata.decodeBase64()))
					if(tmp.size()!=0){
						println " ------------- tmp : ${tmp}"
						r.add([cardId:tmp?.card_id,tradedTime:v?.timestamp,tradedItem:tmp?.item_name])
					}
				}catch(org.codehaus.groovy.grails.web.converters.exceptions.ConverterException e){}
			}
		return r
	}
	
	/**
	 * {
     "datalist": {
         "count": 5,
         "datalist": [
             {
                 "id": "0_c6123160-7240-11e1-b4f8-005056c00008",
                 "timestamp": 1332215832438,
                 "rawdata": 
"eyAiQ2FyZElEIjoiMjMzNDMyNTUyMyIsICJpdGVtIjoiQ29rZSBDb2xhIiB9"
             },
             {
                 "id": "0_6e29eba0-7240-11e1-b4f8-005056c00008",
                 "timestamp": 1332215684954,
                 "rawdata": "YWJjZA=="
             },
             {
                 "id": "0_67f12ab0-723f-11e1-b4f8-005056c00008",
                 "timestamp": 1332215245019,
                 "rawdata": "MQ=="
             },
             {
                 "id": "0_dbb470c0-723e-11e1-b4f8-005056c00008",
                 "timestamp": 1332215009740,
                 "rawdata": "YQ=="
             },
             {
                 "id": "0_ba859140-723e-11e1-b4f8-005056c00008",
                 "timestamp": 1332214954068,
                 "rawdata": "MTIzNDY="
             }
         ]
     }
}


	 * */

	def getMatchPayments(def ts){
		def matchPayments = null
		ts.each { t ->
			if(matchPayments==null &&
			PaymentMatch.countByTransactionA(t)==0 &&
			PaymentMatch.countByTransactionB(t)==0){
				matchPayments = t
			}
		}
		return matchPayments
	}

	def getTheSameTransaction(def cid,def item){
		return PaymentTransaction.findAllByCardIdAndItemName(cid,item)
	}

	//TODO
	Coupon getCoupon(def t){
		if(Coupon.count()==0){//FIXME the init step of quartz job is fast then bootstrap
			new Coupon(item:"e-coupon from iasolution",description:"it's a test coupon").save()
		}
		return Coupon.list()[0]
	}

	private String DEFAULT_USER_NAME = "default"

	ShiroUser getUser(def cardId){
		def u = ShiroUser.findByCardId(cardId)
		if(u==null)
			u = ShiroUser.findByUsername(DEFAULT_USER_NAME)
		return u
	}
}
